package campus.aiit.ssl.service;

import campus.aiit.ssl.dao.BlockDao;
import campus.aiit.ssl.dao.DeviceDao;
import campus.aiit.ssl.dao.StatisticsDao;
import campus.aiit.ssl.domain.model.Block;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

@Service
public class StatisticsService {
    private StatisticsDao statisticsDao;
    private BlockDao blockDao;
    private DeviceDao deviceDao;

    @Autowired
    public StatisticsService(StatisticsDao statisticsDao,BlockDao blockDao,DeviceDao deviceDao){
        this.statisticsDao = statisticsDao;
        this.blockDao = blockDao;
        this.deviceDao = deviceDao;
    }

    public List<Map<String, Object>> getDeviceNum(Long blockId, Long deviceTypeId) {
        return statisticsDao.getDeviceNum(blockId,deviceTypeId);
    }

    public Map<String, Object> DeviceNumOfBlock(Long blockId, Long deviceTypeId) {
        Map<String , Object> map = new HashMap<>();
        Block[] blocks = blockDao.selectById(blockId);
        for(Block block : blocks){
            Map<String , Object> map1 = new HashMap<>();
            map1.put("blockId",block.getId());
            map1.put("blockName",block.getName());
            map1.put("deviceNum",statisticsDao.getDeviceNum(block.getId(),deviceTypeId));
            map.put(block.getName(),map1);
        }
        return map;
    }

    public List<Map<String, Object>> getTotalECOfType(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        return statisticsDao.getTotalECForType(blockId,deviceTypeId,startTime,endTime);
    }


    public Map<String, Object> getTotalECOfAllBlock() {
        List<Map<String, Object>> list = statisticsDao.getTotalECOfAllBlock();
        System.out.println(list);
        Map<String , Object> map = new HashMap<>();
        int sum = 0;
        for (Map<String, Object> m : list) {
            BigDecimal bigDecimal= (BigDecimal)m.get("electricConsume");
            try {
                System.out.println(bigDecimal);
                Integer ec=Integer.parseInt(bigDecimal.toString());
                sum += ec;
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
        map.put("totalEC",sum);
        map.put("maxEC",list.get(list.size()-1).get("electricConsume"));
        map.put("maxECBlock",list.get(list.size()-1).get("blockName"));
        map.put("avgEC",(float)(Math.round(((float)sum/list.size())*100))/100);
        map.put("minEC",list.get(0).get("electricConsume"));
        map.put("minECBlock",list.get(0).get("blockName"));
        return map;
    }

    public Map<String, Object> getECOfBlock(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        Map<String , Object> map = new HashMap<>();
        Block[] blocks = blockDao.selectById(blockId);
        for(Block block : blocks){
            Map<String , Object> map1 = new HashMap<>();
            map1.put("blockId",block.getId());
            map1.put("blockName",block.getName());
            map1.put("ECOfType",statisticsDao.getECOfDeviceType(block.getId(),deviceTypeId,startTime,endTime));
            map.put(block.getName(),map1);
        }
        return map;
    }

    public Map<String, Object> getECOfDevice(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        Map<String , Object> map = new HashMap<>();
        map.put("blockId",blockId);
        map.put("deviceTypeId",deviceTypeId);
        int maxEC = -1;
        int minEC = Integer.MAX_VALUE;
        int totalEC = 0;
        List<Map<String, Object>> list = deviceDao.getDevice(map);
        for (Map<String, Object> m : list) {
            BigInteger bigInteger = (BigInteger)m.get("deviceId");
            Long deviceId = Long.parseLong(bigInteger.toString());
            try{
                List<Map<String, Object>> ecList = statisticsDao.getECOfDevice(deviceId,startTime,endTime);
                try {
                    int lastEC = (int)ecList.get(0).get("electricConsume");
                    int sum = 0;
                    for (Map<String, Object> map1 : ecList) {
                        int ec = (int)map1.get("electricConsume");
                        sum += ec - lastEC;
                        map1.put("electricConsume",ec-lastEC);
                        lastEC = ec;
                    }
                    ecList.remove(0);
                    m.put("EC",sum);
                    m.put("ECOfDay",ecList);
                    totalEC += sum;
                    if(sum > maxEC){
                        maxEC = sum;
                    }
                    if(sum < minEC){
                        minEC = sum;
                    }
                }catch (NullPointerException e){
                    e.printStackTrace();
                }
            }catch(IndexOutOfBoundsException e){}
        }
        Map<String , Object> total = new HashMap<>();
        if(maxEC == -1){
            maxEC = 0;
        }
        if(minEC == Integer.MAX_VALUE){
            minEC = 0;
        }
        total.put("maxEC",maxEC);
        total.put("minEC",minEC);
        total.put("totalEC",totalEC);
        total.put("avgEC",(float)(Math.round(((float)totalEC/list.size())*100))/100);
        Map<String, Object> map2 = new HashMap<>();
        map2.put("total",total);
        map2.put("device",list);
        return map2;
    }

    public List<Map<String, Object>> getDayECOfDeviceType(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        List<Map<String, Object>> date = statisticsDao.getDays(startTime,endTime);
        for (Map<String, Object> map1 : date) {
//            SimpleDateFormat nowDay = new SimpleDateFormat("yyyy-MM-dd");
//            String time = null;
//            try {
//                time = nowDay.format(new Date(nowDay.parse((String) map1.get("createTime")).getTime()-24*60*60*1000));
//            } catch (ParseException e) {
//                e.printStackTrace();
//            }
            map1.put("ECOfDeviceType",statisticsDao.getECOfDeviceType(blockId,deviceTypeId,(String) map1.get("createTime"),(String) map1.get("createTime")));
        }
        return date;
    }

    public List<Map<String, Object>> getDayECOfBlock(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        List<Map<String, Object>> date = statisticsDao.getDays(startTime,endTime);
        for (Map<String, Object> map1 : date) {
            map1.put("ECOfBlock",statisticsDao.getECOfBlock(blockId,deviceTypeId,(String) map1.get("createTime"),(String) map1.get("createTime")));
        }
        return date;
    }


    public List<Map<String, Object>> getECOfDeviceType(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        return statisticsDao.getECOfDeviceType(blockId,deviceTypeId,startTime,endTime);
    }

    public List<Map<String, Object>> getTotalECOfBlock(Long blockId, Long deviceTypeId, String startTime, String endTime) {
        List<Map<String, Object>> mapList = statisticsDao.getTotalDeviceNumOfBlock(deviceTypeId);
        for (Map<String, Object> map : mapList) {
            List<Map<String, Object>> mapList1 = statisticsDao.getECOfDeviceType((Long) map.get("blockId"),deviceTypeId,startTime,endTime);
            int sum = 0;
            for (Map<String, Object> map1 : mapList1) {
                BigDecimal bigDecimal= (BigDecimal)map1.get("electricConsume");
                try {
                    Integer ec=Integer.parseInt(bigDecimal.toString());
                    sum += ec;
                } catch (NullPointerException e){
                    e.printStackTrace();
                }
            }
            map.put("EC",sum);
        }
        return mapList;
    }

    public int getMonthECByDeviceId(Long deviceId, String startTime, String endTime) {
        try {
            int ec = statisticsDao.getMonthECByDeviceId(deviceId,startTime,endTime).intValue();
            return ec;
        }catch (NullPointerException e){
            return 0;
        }
    }

    public Map<String, Object> totalEC(List<Map<String, Object>> mapList) {
        int maxEC = -1;
        int minEC = Integer.MAX_VALUE;
        Map<String, Object> total = new HashMap<>();
        int totalEC = 0;
        for (Map<String, Object> map : mapList) {
            List<Map<String, Object>> mapList1 = (List<Map<String, Object>>) map.get("ECOfType");
            int sum = 0;
            try {
            for (Map<String, Object> map1 : mapList1) {
                BigDecimal bigDecimal= (BigDecimal)map1.get("electricConsume");
                Integer ec = Integer.parseInt(bigDecimal.toString());
                sum += ec;
            }
            }catch (NullPointerException e){ }
            totalEC += sum;
            Map<String, Object> map2 = new HashMap<>();
            map2.putAll(map);
            if(sum > maxEC){
                maxEC = sum;
                map2.remove("ECOfType");
                map2.put("EC",maxEC);
                total.put("maxEC",map2);
            }
            if(sum < minEC){
                minEC = sum;
                map2.remove("ECOfType");
                map2.put("EC",minEC);
                total.put("minEC",map2);
            }
        }
        total.put("totalEC",totalEC);
        total.put("avgEC",(float)(Math.round(((float)totalEC/mapList.size())*100))/100);
        return total;
    }

}
